package com.mrdeer.web.controller.sys;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.mrdeer.common.JSONResult;
import com.mrdeer.common.constants.CommonConstant;
import com.mrdeer.common.entity.dto.DepartmentDTO;
import com.mrdeer.common.entity.sys.Department;
import com.mrdeer.common.entity.sys.DepartmentHeader;
import com.mrdeer.common.entity.sys.User;
import com.mrdeer.common.exception.BusinessException;
import com.mrdeer.common.tools.CommonUtil;
import com.mrdeer.common.tools.RedisTemplateHelper;
import com.mrdeer.security.SecurityUtil;
import com.mrdeer.web.service.sys.SysDepartmentHeaderService;
import com.mrdeer.web.service.sys.SysDepartmentService;
import com.mrdeer.web.service.sys.SysRoleDepartmentService;
import com.mrdeer.web.service.sys.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
@Transactional
@Api(tags = "部门管理接口")
@CacheConfig(cacheNames = "department")
@RequestMapping("/mrdeer/department")
public class SysDepartmentController {

    @Resource
    private SysDepartmentService sysDepartmentService;

    @Resource
    private SysUserService sysUserService;

    @Resource
    private SysRoleDepartmentService sysRoleDepartmentService;

    @Resource
    private SysDepartmentHeaderService sysDepartmentHeaderService;

    @Resource
    private RedisTemplateHelper redisTemplate;

    @Resource
    private SecurityUtil securityUtil;

    @ApiOperation(value = "通过parentId获取")
    @RequestMapping(value = "/getByParentId/{parentId}", method = RequestMethod.GET)
    public JSONResult getByParentId(@PathVariable String parentId, @ApiParam("是否开始数据权限过滤") @RequestParam(required = false, defaultValue = "true") Boolean openDataFilter) {
        List<Department> list;
        User u = securityUtil.getCurrUser();
        String key = "department::" + parentId + ":" + u.getId() + "_" + openDataFilter;
        String v = redisTemplate.get(key);
        if (StrUtil.isNotBlank(v)) {
            list = new Gson().fromJson(v, new TypeToken<List<Department>>() {
            }.getType());
            return JSONResult.ok(list);
        }
        list = sysDepartmentService.findByParentIdOrderBySortOrder(parentId, openDataFilter);
        setInfo(list);
        redisTemplate.set(key, new GsonBuilder().create().toJson(list), 15L, TimeUnit.DAYS);
        return JSONResult.ok(list);
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ApiOperation(value = "添加")
    public JSONResult add(@RequestBody DepartmentDTO department) {
        Department d = sysDepartmentService.add(department);
        //如果不是添加的一级 判断设置上级为父节点标识
        if (!CommonConstant.PARENT_ID.equals(department.getParentId())) {
            Department parent = sysDepartmentService.getById(department.getParentId());
            if (parent.getIsParent() == null || !parent.getIsParent()) {
                parent.setIsParent(true);
                sysDepartmentService.updateById(parent);
            }
        }
        //更新缓存
        redisTemplate.deleteByPattern("department::*");
        return JSONResult.ok("添加成功");
    }

    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    @ApiOperation(value = "编辑")
    public JSONResult edit(Department department,
                           @RequestParam(required = false) String[] mainHeader,
                           @RequestParam(required = false) String[] viceHeader) {
        if (department.getId().equals(department.getParentId())) {
            return JSONResult.errorMsg("上级节点不能为自己");
        }
        Department old = sysDepartmentService.getById(department.getId());
        String oldParentId = old.getParentId();
        sysDepartmentService.updateById(department);
        Department d = sysDepartmentService.getOne(new LambdaQueryWrapper<Department>().eq(Department::getId, department.getId()));
        //先删除原数据
        sysDepartmentHeaderService.deleteByDepartmentId(department.getId());
        List<DepartmentHeader> headers = new ArrayList<>();
        if (mainHeader != null) {
            for (String id : mainHeader) {
                DepartmentHeader dh = new DepartmentHeader().setUserId(id).setDepartmentId(d.getId()).setType(CommonConstant.HEADER_TYPE_MAIN);
                headers.add(dh);
            }
        }
        if (viceHeader != null) {
            for (String id : viceHeader) {
                DepartmentHeader dh = new DepartmentHeader().setUserId(id).setDepartmentId(d.getId()).setType(CommonConstant.HEADER_TYPE_VICE);
                headers.add(dh);
            }
        }
        //批量保存
        sysDepartmentHeaderService.saveOrUpdateBatch(headers);
        //如果该节点不是一级节点，且修改了级别 判断上级还有无子节点
        if (!CommonConstant.PARENT_ID.equals(oldParentId) && !oldParentId.equals(department.getParentId())) {
            Department parent = sysDepartmentService.getOne(new QueryWrapper<Department>().eq("parent_id", oldParentId));
            List<Department> children = sysDepartmentService.findByParentIdOrderBySortOrder(parent.getId(), false);
            if (parent != null && (children == null || children.isEmpty())) {
                parent.setIsParent(false);
                sysDepartmentService.updateById(parent);
            }
        }
        //若修改了部门名称
        if (!old.getTitle().equals(department.getTitle())) {
            sysUserService.updateDepartmentTitle(department.getId(), department.getTitle());
            //删除所有用户缓存
            redisTemplate.deleteByPattern("user:*");
        }
        //手动删除所有部门缓存
        redisTemplate.deleteByPattern("department:*");
        return JSONResult.ok("编辑成功");
    }

    @RequestMapping(value = "/delByIds", method = RequestMethod.POST)
    @ApiOperation(value = "批量通过id删除")
    public JSONResult delByIds(@RequestParam String ids) {
        String[] idList = ids.split(",");
        for (String id : idList) {
            deleteRecursion(id, idList);
        }
        //手动删除所有部门缓存
        redisTemplate.deleteByPattern("department:*");
        //删除数据权限缓存
        redisTemplate.deleteByPattern("userRole::depIds:*");
        return JSONResult.ok("批量通过id删除数据成功");
    }

    public void deleteRecursion(String id, String[] ids) {
        List<User> list = sysUserService.findByDepartmentId(id);
        if (list != null && list.size() > 0) {
            throw new BusinessException("删除失败，包含正被用户使用关联的部门");
        }
        //获得其父节点
        Department dep = sysDepartmentService.getById(id);
        Department parent = null;
        if (dep != null && StrUtil.isNotBlank(dep.getParentId())) {
//            parent = departmentService.getOne(new QueryWrapper<Department>().eq("parent_id", dep.getParentId()));
            parent = sysDepartmentService.getById(dep.getParentId());
        }
        sysDepartmentService.delete(id);
        //删除关联数据权限
        sysRoleDepartmentService.deleteByDepartmentId(id);
        //删除关联部门负责人
        sysDepartmentHeaderService.deleteByDepartmentId(id);
        //TODO:删除流程关联节点
        //判断父节点是否还有子节点
        if (parent != null) {
            List<Department> childrenDeps = sysDepartmentService.findByParentIdOrderBySortOrder(parent.getId(), false);
            if (childrenDeps == null || childrenDeps.isEmpty()) {
                parent.setIsParent(false);
                sysDepartmentService.updateById(parent);
            }
        }
        //递归删除
        List<Department> departments = sysDepartmentService.findByParentIdOrderBySortOrder(id, false);
        for (Department d : departments) {
            if (!CommonUtil.judgeIds(d.getId(), ids)) {
                deleteRecursion(d.getId(), ids);
            }
        }
    }

    @RequestMapping(value = "/search", method = RequestMethod.GET)
    @ApiOperation(value = "部门名模糊搜索")
    public JSONResult searchByTitle(@RequestParam String title, @ApiParam("是否开始数据权限过滤") @RequestParam(required = false, defaultValue = "true") Boolean openDataFilter) {
        List<Department> list = sysDepartmentService.findByTitleLikeOrderBySortOrder("%" + title + "%", openDataFilter);
        setInfo(list);
        return JSONResult.ok(list);
    }

    public void setInfo(List<Department> list) {
        //lambda表达式
        list.forEach(item -> {
            if (!CommonConstant.PARENT_ID.equals(item.getParentId())) {
                Department parent = sysDepartmentService.getOne(new QueryWrapper<Department>().eq("title", item.getTitle()));
                item.setParentTitle(parent.getTitle());
            } else {
                item.setParentTitle("一级部门");
            }
            //设置负责人
            item.setMainHeader(sysDepartmentHeaderService.findHeaderByDepartmentId(item.getId(), CommonConstant.HEADER_TYPE_MAIN));
            item.setViceHeader(sysDepartmentHeaderService.findHeaderByDepartmentId(item.getId(), CommonConstant.HEADER_TYPE_VICE));
        });
    }
}
